<?php
date_default_timezone_set('Asia/Shanghai');

const MY_EMAIL = "nice2m@163.com";

run();
//test();

function test()
{
    $html = file_get_contents('detail-normal2.html');
    $ret  = get_html_info($html);
    var_dump($ret);
}


// 运行
function run()
{
    $path = sprintf("%s%swish-list.json", __DIR__, DIRECTORY_SEPARATOR);
    $list = json_decode(file_get_contents($path), true);
    if (!$list) {
        my_log("empty task");
        return;
    }

    my_log("start!");
    $list = each_task($list);
    file_put_contents($path, json_encode($list, JSON_UNESCAPED_UNICODE));
    my_log("done!");
}

// 执行一次任务
function each_task($list)
{
    my_log("task count:" . count($list));

    foreach ($list as $idx => &$item) {
        sleep(3);

        list(, $wish_price, $url, $title, , $create_time) = $item;
        my_log("checkin {$title}");
        $html = curl_get($url);
        $info = get_html_info($html);
        if (!is_array($info)) {
            my_log("check field");
            continue;
        }

        // 计算价格
        list($cancel, $curr_rmb, $curr_price) = calc_price($info, $item);
        if ($cancel) {
            my_log("current price:¥{$curr_rmb}({$info['finalPrice']}), wish price:¥{$wish_price} ");
            continue;
        }

        // 能不能发邮件
        my_log("need send mail:{$title}");
        send_mail_handle($url, function () use ($title, $url, $curr_price, $curr_rmb) {
            my_log("send mail:{$title}");
            return send_mail($title, $url, $curr_price, $curr_rmb);
        });

        $item = [round($curr_price, 2), round($wish_price, 2), $url, $title, time(), intval($create_time)];
    }
    return $list;
}

// xpath 获取值
function xquery(&$html, $expr)
{
    $dom = new DOMDocument();
    @$dom->loadHTML($html);
    $xPath = new DOMXPath($dom);

    /* @var DOMNodeList $elements */
    $elements = $xPath->query($expr);
    if ($elements) {
        $i = $elements->item(0);
        if ($i) {
            return $i->nodeValue;
        }
    }
    return false;
}

// 获取价格
function get_html_info($html)
{
    $finalPrice = xquery($html, '//span[@data-qa="mfeCtaMain#offer0#finalPrice"]');
    if ($finalPrice === false) {
        return false;
    }
    $originalPrice      = xquery($html, '//span[@data-qa="mfeCtaMain#offer0#originalPrice"]');
    $discountInfo       = xquery($html, '//span[@data-qa="mfeCtaMain#offer0#discountInfo"]');
    $discountDescriptor = xquery($html, '//span[@data-qa="mfeCtaMain#offer0#discountDescriptor"]');

    return [
        'finalPrice'         => $finalPrice,
        'originalPrice'      => $originalPrice ?? '',
        'discountInfo'       => $discountInfo ?? '',
        'discountDescriptor' => $discountDescriptor ?? '',
    ];
}

// 计算价格
function calc_price($info, $item)
{
    list(, $wish_price, $url, $title, , $create_time) = $item;

    $curr_price = fetch_price($info['finalPrice']);
    // 转换为人民币比较
    $curr_rmb = 0;
    $er       = exchange_rate();
    if ($er !== -1) {
        $curr_rmb = $er * $curr_price;
    }
    return [$curr_rmb > $wish_price, $curr_rmb, $curr_price];
}

// http请求
function curl_get($url, $header = [])
{
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_TIMEOUT, 60);
    // curl_setopt($curl, CURLOPT_TIMEOUT_MS, 500);

    $cookie_file = sprintf("%s%spsprices.cookie", __DIR__, DIRECTORY_SEPARATOR);
    curl_setopt($curl, CURLOPT_COOKIEFILE, $cookie_file);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
    $data = curl_exec($curl);

    if (curl_error($curl)) {
        my_log("Error: " . curl_error($curl) . PHP_EOL);
    } else {
        curl_close($curl);
    }
    return $data;
}

// 使用shell的mailx发邮件
function send_mail($title, $content, $price, $rmb)
{
    $title   = sprintf("PS Store,%s 降价了", $title);
    $content = sprintf('当前价格:RMB%.2f(HKD%.2f), PSN商店地址:%s', $price, $rmb, $content);
    $cmd     = sprintf('echo "%s" | mailx -s "%s" %s', $content, $title, MY_EMAIL);
    $ret     = exec($cmd);
    if (is_string($ret) and $ret) {
        my_log("发送失败:{$ret}");
        return false;
    }
    return true;
}

// 能不能发邮件
function send_mail_handle($url, $call)
{
    $key = md5($url);
    $now = time();

    $dir  = sys_get_temp_dir();
    $path = sprintf("%s%spsprices.record", $dir, DIRECTORY_SEPARATOR);
    if (file_exists($path)) {
        $content = file_get_contents($path);
        if (is_string($content)) {
            $data = json_decode($content, true);
        }
    } else {
        file_put_contents($path, '');
    }

    if (!isset($data) || !is_array($data)) {
        $data = [];
    }

    // 3天内不重复发送
    $latest_time = $data[$key] ?? 0;
    if ($latest_time > ($now - 3 * 86400)) {
        my_log("最近发送时间:" . date("Y-m-d H:i:s", $latest_time));
        return false;
    }
    if ($call instanceof \Closure) {
        $ret = $call();
        if ($ret !== true) {
            return false;
        }
    }
    $data[$key] = $now;
    file_put_contents($path, json_encode($data));
    return true;
}

// 输出
function my_log(...$values)
{
    $str = implode(" ", $values);
    echo sprintf("[%s] %s\n", date('Y-m-d H:i:s'), $str);
}

// 获取汇率
function exchange_rate()
{
    // 取历史文件
    $dir  = sys_get_temp_dir();
    $cur  = date('Y-m-d');
    $path = sprintf("%s%spsprices.exchange_rate.%s", $dir, DIRECTORY_SEPARATOR, $cur);
    if (file_exists($path)) {
        $er = file_get_contents($path);
        if (is_string($er) and $er) {
            return floatval($er);
        }
    }

    // 每天更新数据
    $html = curl_get('https://www.usd-cny.com/');
    $html = iconv("GB2312", "UTF-8//IGNORE", $html);
    $patt = '/<tr><td class="bz"><a href=".*?">港币<\/a><\/td><td>[0-9\.]+<\/td>'
        . '<td>[0-9\.]+<\/td><td>[0-9\.]+<\/td><td>([0-9\.]+)<\/td><\/tr>/is';
    $ret  = preg_match($patt, $html, $match);
    if ($ret > 0) {
        $er = floatval($match[1]) / 100.0;
        file_put_contents($path, '' . $er);
        $prev      = date('Y-m-d', time() - 86400);
        $prev_path = sprintf("%s%spsprices.exchange_rate.%s", $dir, DIRECTORY_SEPARATOR, $prev);
        if (file_exists($prev_path)) {
            unlink($prev_path);
        }
        return $er;
    }
    my_log("港币汇率获取失败");
    return -1;
}

// 获取价格 HK$284.00
function fetch_price($s)
{
    if (!is_string($s)) {
        return 0.0;
    }
    $p = '/[0-9.]+/iu';
    if (1 === preg_match($p, $s, $m)) {
        return floatval($m[0]);
    }
    return 0.0;
}